package com.example.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.common.constant.ProductConstant;
import com.example.common.to.SkuReductionTo;
import com.example.common.to.SpuBoundTo;
import com.example.common.to.es.SkuEsModel;
import com.example.common.utils.R;
import com.example.product.entity.*;
import com.example.product.feign.CouponFeignService;
import com.example.product.feign.SearchFeignService;
import com.example.product.feign.WareSkuFeignService;
import com.example.product.service.*;
import com.example.product.vo.*;
import jdk.nashorn.internal.ir.CallNode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.utils.PageUtils;
import com.example.common.utils.Query;

import com.example.product.dao.SpuInfoDao;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;


@Slf4j
@Service("spuInfoService")
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {

    @Autowired
    private SpuInfoDescService spuInfoDescService;
    @Autowired
    private SpuImagesService spuImagesService;
    @Autowired
    private AttrService attrService;
    @Autowired
    private ProductAttrValueService productAttrValueService;
    @Autowired
    private SkuInfoService skuInfoService;
    @Autowired
    private SkuImagesService skuImagesService;
    @Autowired
    private SkuSaleAttrValueService skuSaleAttrValueService;
    @Autowired
    private CouponFeignService couponFeignService;
    @Autowired
    private BrandService brandService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private WareSkuFeignService wareSkuFeignService;
    @Autowired
    private SearchFeignService searchFeignService;
    @Autowired
    private SpuInfoService spuInfoService;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                new QueryWrapper<SpuInfoEntity>()
        );

        return new PageUtils(page);
    }

    @Transactional
    @Override
    public void saveSpuInfo(SpuSaveVo spuSaveVo) {
        if (spuSaveVo != null) {
            // 1. 保存spu基本信息 pms_spu_info
            SpuInfoEntity spuInfoEntity = new SpuInfoEntity();
            BeanUtils.copyProperties(spuSaveVo,spuInfoEntity);
            spuInfoEntity.setCreateTime(new Date());
            spuInfoEntity.setUpdateTime(new Date());
            this.save(spuInfoEntity);

            // 2. 保存spu的描述图片 pms_spu_info_desc
            List<String> descriptions = spuSaveVo.getDecript();
            SpuInfoDescEntity spuInfoDescEntity = new SpuInfoDescEntity();
            spuInfoDescEntity.setSpuId(spuInfoEntity.getId());
            spuInfoDescEntity.setDecript(String.join(",",descriptions));
            spuInfoDescService.save(spuInfoDescEntity);

            // 3. 保存spu的图片集 pms_spu_images
            List<String> images = spuSaveVo.getImages();
            spuImagesService.saveImages(spuInfoEntity.getId(),images);

            // 4. 保存spu的规格参数 pms_product_attr_value
            List<BaseAttrs> baseAttrs = spuSaveVo.getBaseAttrs();
            if (baseAttrs != null && baseAttrs.size() > 0) {
                List<ProductAttrValueEntity> collect = baseAttrs.stream().map(attr -> {
                    ProductAttrValueEntity valueEntity = new ProductAttrValueEntity();
                    valueEntity.setAttrId(attr.getAttrId());
                    AttrEntity attrEntity = attrService.getById(attr.getAttrId());
                    if (attrEntity != null) {
                        valueEntity.setAttrName(attrEntity.getAttrName());
                    }
                    valueEntity.setAttrValue(attr.getAttrValues());
                    valueEntity.setQuickShow(attr.getShowDesc());
                    valueEntity.setSpuId(spuInfoEntity.getId());
                    return valueEntity;
                }).collect(Collectors.toList());
                productAttrValueService.saveBatch(collect);
            }

            // 5. 保存spu的积分信息 sms_spu_bounds
            Bounds bounds = spuSaveVo.getBounds();
            SpuBoundTo spuBoundTo = new SpuBoundTo();
            BeanUtils.copyProperties(bounds,spuBoundTo);
            spuBoundTo.setSpuId(spuInfoEntity.getId());
            couponFeignService.save(spuBoundTo);

            // 6. 保存当前spu对应的所有sku信息
            // 6.1 保存sku的基本信息 pms_sku_info
            List<Skus> skus = spuSaveVo.getSkus();
            if (skus != null && skus.size() > 0) {
                skus.forEach(item -> {
                    String defaultImg = null;
                    for (Images image : item.getImages()) {
                        if (image.getDefaultImg() == 1) {
                            defaultImg = image.getImgUrl();
                        }
                    }

                    SkuInfoEntity skuInfoEntity = new SkuInfoEntity();
                    BeanUtils.copyProperties(item,skuInfoEntity);
                    skuInfoEntity.setSkuDefaultImg(defaultImg);
                    skuInfoEntity.setBrandId(spuInfoEntity.getBrandId());
                    skuInfoEntity.setCatalogId(spuInfoEntity.getCatalogId());
                    skuInfoEntity.setSaleCount(0L);
                    skuInfoEntity.setSpuId(spuInfoEntity.getId());
                    skuInfoService.save(skuInfoEntity);

                    // 6.2 保存sku的图片信息 pms_sku_images
                    Long skuId = skuInfoEntity.getSkuId();
                    List<Images> images1 = item.getImages();
                    if (images1 != null && images1.size() > 0) {
                        List<SkuImagesEntity> skuImageEntities = images1.stream().map(img -> {
                            SkuImagesEntity skuImagesEntity = new SkuImagesEntity();
                            skuImagesEntity.setSkuId(skuId);
                            skuImagesEntity.setImgUrl(img.getImgUrl());
                            skuImagesEntity.setDefaultImg(img.getDefaultImg());
                            return skuImagesEntity;
                        }).filter(entity -> {
                            return !StringUtils.isEmpty(entity.getImgUrl());
                        }).collect(Collectors.toList());
                        skuImagesService.saveBatch(skuImageEntities);
                    }

                    // 6.3 保存sku的销售属性信息 pms_sku_sale_attr_value
                    List<Attr> attrs = item.getAttr();
                    if (attrs != null && attrs.size() > 0) {
                        List<SkuSaleAttrValueEntity> skuSaleAttrValueEntities = attrs.stream().map(attr -> {
                            SkuSaleAttrValueEntity skuSaleAttrValueEntity = new SkuSaleAttrValueEntity();
                            BeanUtils.copyProperties(attr, skuSaleAttrValueEntity);
                            skuSaleAttrValueEntity.setSkuId(skuId);
                            return skuSaleAttrValueEntity;
                        }).collect(Collectors.toList());
                        skuSaleAttrValueService.saveBatch(skuSaleAttrValueEntities);
                    }

                    // 6.4 保存sku的优惠、满减等信息 sms_sku_ladder sms_sku_full_reduction sms_member_price
                    SkuReductionTo skuReductionTo = new SkuReductionTo();
                    BeanUtils.copyProperties(item,skuReductionTo);
                    skuReductionTo.setSkuId(skuId);
                    if (skuReductionTo.getFullCount() > 0 || skuReductionTo.getFullPrice().compareTo(new BigDecimal("0")) == 1) {
                        couponFeignService.saveSkuReduction(skuReductionTo);
                    }
                });
            }
        }
    }

    @Override
    public PageUtils queryPageByCondition(Map<String, Object> params) {
        QueryWrapper<SpuInfoEntity> wrapper = new QueryWrapper<>();

        String key = (String)params.get("key");
        String status = (String) params.get("status");
        String brandId = (String) params.get("brandId");
        String catelogId = (String) params.get("catelogId");

        if (!StringUtils.isEmpty(key)) {
            wrapper.and(wp -> {
                wp.eq("id",key).or().like("spu_name",key);
            });
        }
        if (!StringUtils.isEmpty(status)) {
            wrapper.eq("publish_status",status);
        }
        if (!StringUtils.isEmpty(brandId)) {
            wrapper.eq("brand_id",brandId);
        }
        if (!StringUtils.isEmpty(catelogId)) {
            wrapper.eq("catalog_id",catelogId);
        }

        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                wrapper
        );
        return new PageUtils(page);
    }

    @Override
    public void up(Long spuId) {
        // 1. 查询出spu对应的所有sku
        List<SkuInfoEntity> skus = skuInfoService.list(new QueryWrapper<SkuInfoEntity>().eq("spu_id", spuId));
        if (skus == null || skus.size() < 1) {
            return;
        }
        // 2. 查询当前spu所有可以检索的规格属性（基本属性）
        List<ProductAttrValueEntity> spuBaseAttrs = productAttrValueService.list(new QueryWrapper<ProductAttrValueEntity>().eq("spu_id", spuId));
        List<Long> collect = null;
        if (spuBaseAttrs != null && spuBaseAttrs.size() > 0) {
            collect = spuBaseAttrs.stream().map(item -> {
                return item.getAttrId();
            }).collect(Collectors.toList());
        }
        List<AttrEntity> attrs = null;
        if (collect != null && collect.size() > 0) {
            attrs = attrService.list(new QueryWrapper<AttrEntity>().in("attr_id", collect).eq("search_type",1));
        }
        // 3. 封装每个SkuEsModel的信息
        // 查询所有sku是否有库存（远程调用）
        List<Long> skuIds = skus.stream().map(sku -> {
            return sku.getSkuId();
        }).collect(Collectors.toList());
        Map<Long,Boolean> skusHasStock = null;
        try {
            skusHasStock = wareSkuFeignService.skuIsStock(skuIds);
        }catch (Exception e) {
            log.error("gmall-ware服务调用异常 ==================>{}",e.getMessage());
        }
        Map<Long,Boolean> finalSkusHasStock  = skusHasStock;
        // 封装SkuEsModel
        List<AttrEntity> baseAttrs = attrs;
        List<SkuEsModel> skuEsModels = skus.stream().map(item -> {
            SkuEsModel skuEsModel = new SkuEsModel();
            BeanUtils.copyProperties(item, skuEsModel);
            /** 需要单独处理的字段
                子段名不一样 skuPrice skuImg
                不存在的字段 hotScore brandName brandImg catalogName hasStock
                attr -> attrId attrName attrValue
             */
            skuEsModel.setSkuPrice(item.getPrice());
            skuEsModel.setSkuImg(item.getSkuDefaultImg());
            skuEsModel.setHotScore(0);
            // 设置是否有库存 调用库存服务，查询该sku是否有库存
            skuEsModel.setHasStock(finalSkusHasStock.get(item.getSkuId()));
            // 设置spu对应的品牌brandName brandImg
            Collection<BrandEntity> brandEntities = brandService.listByIds(Collections.singletonList(item.getBrandId()));
            if (brandEntities != null && brandEntities.size() > 0) {
                BrandEntity[] brandEntities1 = brandEntities.toArray(new BrandEntity[brandEntities.size()]);
                skuEsModel.setBrandName(brandEntities1[0].getName());
                skuEsModel.setBrandImg(brandEntities1[0].getLogo());
            }
            // 设置spu对应的分类catalogName
            Collection<CategoryEntity> categoryEntities = categoryService.listByIds(Collections.singletonList(item.getCatalogId()));
            if (categoryEntities != null && categoryEntities.size() > 0) {
                CategoryEntity[] categoryEntities1 = categoryEntities.toArray(new CategoryEntity[categoryEntities.size()]);
                skuEsModel.setCatalogName(categoryEntities1[0].getName());
            }

            // 设置规格参数
            if (baseAttrs != null && baseAttrs.size() > 0) {
                List<SkuEsModel.Attr> attrEsModels = baseAttrs.stream().map(att -> {
                    SkuEsModel.Attr attrEsModel = new SkuEsModel.Attr();
                    BeanUtils.copyProperties(att, attrEsModel);
                    attrEsModel.setAttrValue(att.getValueSelect());
                    return attrEsModel;
                }).collect(Collectors.toList());
                skuEsModel.setAttrs(attrEsModels);
            }
            return skuEsModel;
        }).collect(Collectors.toList());

        // 4. 调用检索服务将所有该spu下的sku (skuEsModels) 存到ES
        try {
            R r = searchFeignService.productStatusUp(skuEsModels);
            if (r.getCode() == 0) {
                // 上架成功,修改spu状态
                spuInfoService.update(new UpdateWrapper<SpuInfoEntity>().set("publish_status", ProductConstant.StatusEnum.SPU_DOWN).eq("id",spuId));
            } else {
                // 上架失败
                // TODO 重复调用， 接口幂等性
            }
        }catch (Exception e) {
            log.error("SpuInfoServiceImpl =========================> {}",e.getMessage());
        }
    }

}